<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>俄罗斯方块--2018-06-29</title>
    <script src="js/jquery.min.js"></script>
    <style>
        #mainBoard{position:relative;}
        .smallBox{position: absolute;}
    </style>
</head>
<body style="padding-top:40px;">
    <div style="text-align:center;">
        <button id="startGame">开始游戏</button>
    </div>
</body>
</html>
<script>
    //只有两个对象，面板对象+方块对象
    $().ready(function(){
        //面板对象:
        function mainBoard(xNum,yNum,width){
            this.xNum = xNum;
            this.yNum = yNum;
            this.width = width;
            this.id = "mainBoard";
            //二维数组，第一维代表第几列，第二维代表第几行，从上到下表示。1代表有，0代表没有
            this.mainBArr = new Array();
            this.show = function(){
                var mainEle = $("<div id='"+this.id+"'></div>");
                mainEle.css({
                    width:parseInt(xNum*this.width),
                    height:parseInt(yNum*this.width),
                    position:"relative",
                    border:"1px solid #828282",
                    margin:" 0 auto"
                })
                $("body").append(mainEle);
                

                for(var i=0;i<xNum;i++){
                    this.mainBArr[i] = [];
                    for(var j=0;j<yNum;j++){
                        this.mainBArr[i][j] = {x:i,y:j,status:0};
                        var sBox = $("<div class='smallBox'></div>");
                        sBox.css({
                                width:this.width,
                                height:this.width,
                                left:i*this.width,
                                top:j*this.width,
                                // border:"1px solid #828282",
                                borderLeft:"none"
                            });

                        if(j == yNum - 1){
                            sBox.css("borderBottom","none");
                        }else{
                            sBox.css("borderTop","none");
                        }
                        
                        if(i == xNum - 1){
                            sBox.css("borderRight","none");
                        }
                        mainEle.append(sBox);
                    }
                }
            }
        }

        
        //方块对象;方块对象总共有7种I,O,J,L,S,Z,T
        function block(Board,initX,initY){
            var color = ["pink","skyblue","yellowgreen","plum","gold","lightgrey"];
            this.active = true;
            this.coo = [{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0}];
            this.type = '';
            this.width = Board.width;
            this.color = color[Math.floor(Math.random() * color.length)];
            //生成方块中的小方格;
            this._createPort = function(coo){
                for(var i=0;i<4;i++){
                    eval("this.ele"+i+"= $(\"<div class='port'></div>\")");
                    eval("this.ele"+i+".css({\
                        position:\"absolute\",\
                        width:this.width,\
                        height:this.width,\
                        left:this.width * coo[i].x,\
                        top:this.width * coo[i].y,\
                        backgroundColor:this.color,\
                        border:\"1px solid #828282\"\
                    })");
                    eval("$(\"#\"+Board.id).append(this.ele"+i+")");

                }
            }
            //改变坐标;
            this._changePosition = function(coo){
                for(var i=0;i<4;i++){
                    eval("this.ele"+i+".css({\
                        left:this.width * coo[i].x,\
                        top:this.width * coo[i].y,\
                    })");
                }
            }
            //随机生成方块的方法;
            this.create = function(){
                var type = Math.floor((Math.random() * 7));
                switch(type){
                    case 0:  //I形方块
                        this.type = 'I';
                        this.coo = [{x:initX,y:initY},{x:initX+1,y:initY},{x:initX+2,y:initY},{x:initX+3,y:initY}];
                        this._createPort(this.coo);
                    break;
                    case 1: //O形方块
                        this.type = "O";
                        this.coo = [{x:initX+1,y:initY},{x:initX+2,y:initY},{x:initX+1,y:initY+1},{x:initX+2,y:initY+1}];
                        this._createPort(this.coo);
                    break;
                    case 2: //J形方块
                        this.type = "J";
                        this.coo = [{x:initX+1,y:initY},{x:initX+1,y:initY+1},{x:initX+2,y:initY+1},{x:initX+3,y:initY+1}];
                        this._createPort(this.coo);
                    break;
                    case 3: //L形方块
                        this.type = "L";
                        this.coo = [{x:initX+3,y:initY},{x:initX+1,y:initY+1},{x:initX+2,y:initY+1},{x:initX+3,y:initY+1}];
                        this._createPort(this.coo);
                    break;
                    case 4: //S形方块
                        this.type = "S";
                        this.coo = [{x:initX+3,y:initY},{x:initX+2,y:initY},{x:initX+2,y:initY+1},{x:initX+1,y:initY+1}];
                        this._createPort(this.coo);
                    break;
                    case 5: //Z形方块
                        this.type = "Z";
                        this.coo = [{x:initX+1,y:initY},{x:initX+2,y:initY},{x:initX+2,y:initY+1},{x:initX+3,y:initY+1}];
                        this._createPort(this.coo);
                    break;
                    case 6: //T形方块
                        this.type = "T";
                        this.coo = [{x:initX+1,y:initY},{x:initX+2,y:initY},{x:initX+3,y:initY},{x:initX+2,y:initY+1}];
                        this._createPort(this.coo);
                    break;
                }
            }

            //边界检查
            this.checkTouch = function(coo){
                for(var i=0;i<4;i++){
                    var x = coo[i].x;
                    var y = coo[i].y;

                    if(x < 0 || (x > Board.xNum - 1) || (y > Board.yNum - 1) || ( y < 0) ){
                        return false;
                    }    
                    if(Board.mainBArr[x][y].status){
                        return false;
                    }               
                }
                return true;
            }
            //当方块停止活动之后改变面板的值;
            this.changeStatus = function(){ 
                if(!this.active){
                    for(var i =0 ;i<this.coo.length;i++){
                        var x = this.coo[i].x;
                        var y = this.coo[i].y;
                        eval("this.ele"+i+".attr({\
                            \"data-Y\":\""+y+"\",\
                            \"data-X\":\""+x+"\"\
                         })");
    
                        Board.mainBArr[x][y].status = 1;
                    }
                }
            }
            //消除方块;
            this.destroy = function(){
                var destroyY_arr = new Array();
                for(var i=0;i<Board.mainBArr[0].length;i++){
                    var count = 0;
                    for(var j=0;j<Board.mainBArr.length;j++){
                        if(Board.mainBArr[j][i].status == 1){
                            count++;
                        }
                    }
                    if(count >= Board.mainBArr.length){
                        destroyY_arr.push(i)
                    }
                }
                for(var i=0;i<destroyY_arr.length;i++){
                    $("div[data-Y="+destroyY_arr[i]+"]").remove();
                    for(var j=0;j<Board.mainBArr.length;j++){
                        Board.mainBArr[j][destroyY_arr[i]].status = 0;
                    }
                }
                var destroyLen = destroyY_arr.length;
              
                var width = this.width
                if(destroyLen>0){   //消除之后，改变两个对象的相应属性值;
                    var minVal =  parseInt(Math.min.apply(null,destroyY_arr));
                    $(".port").each(function(index){
                        var currentY = parseInt($(this).attr("data-Y"));
                        var currentTop = $(this).css("top").slice(0,-2);
                        if(currentY < minVal){
                            $(this).css("top",parseInt(currentTop) + parseInt(destroyLen * width));
                            $(this).attr("data-Y",currentY+destroyLen);

                            var x = $(this).attr("data-X");
                            Board.mainBArr[x][currentY].status = 0;
                            Board.mainBArr[x][currentY+destroyLen].status = 1;
                        }
                    })
                }
                return destroyLen;
            }
            //方块移动方法；
            this.move = function(code){
                switch(code){
                    case 37: //左
                        for(var i=0;i<this.coo.length;i++){
                            this.coo[i].x-=1; 
                        }
                        if(this.checkTouch(this.coo)){
                            this._changePosition(this.coo);
                        }else{  //如果触边了就将坐标还原;
                            for(var i=0;i<this.coo.length;i++){
                                this.coo[i].x+=1; 
                            }
                        }
                    break;
                    case 39: //右
                        for(var i=0;i<this.coo.length;i++){
                            this.coo[i].x+=1; 
                        }
                        if(this.checkTouch(this.coo)){
                            this._changePosition(this.coo);
                        }else{  //如果触边了就将坐标还原;
                            for(var i=0;i<this.coo.length;i++){
                                this.coo[i].x-=1; 
                            }
                        }
                        
                    break;
                    case 40:  //下
                        for(var i=0;i<this.coo.length;i++){
                            this.coo[i].y+=1; 
                        }
                       
                        if(this.checkTouch(this.coo)){
                            this._changePosition(this.coo);
                        }else{  //如果触边了就将坐标还原;
                            for(var i=0;i<this.coo.length;i++){
                                this.coo[i].y-=1; 
                            }
                            //消除方块与改变面板值;
                            this.active = false;
                            this.changeStatus();
                            //this.destroy();
                        }
                    break;
                }
            }
            //检测游戏是否结束;
            this.CheckGameOver = function(){
                if(!this.active){
                    for(var i=0;i<4;i++){
                        var y = this.coo[i].y;
                        if(y <= 0 ){
                            //alert("Game Over");
                            return true; 
                        }  
                    }
                }
                return false;
            }
            //计时器里面的自动下移;
            this.AutoMoveDown = function(){
                for(var i=0;i<this.coo.length;i++){
                        this.coo[i].y+=1; 
                    }
    
                if(this.checkTouch(this.coo)){
                    this._changePosition(this.coo);
                }else{  //如果触边了就将坐标还原;
                    for(var i=0;i<this.coo.length;i++){
                        this.coo[i].y-=1; 
                    }
                    //消除方块与改变面板值;
                    this.active = false;
                    this.changeStatus();
                    //this.destroy();
                }
            }
            //方块旋转方法;I,O,J,L,S,Z,T
            this.rotate = function(keyCode){
                if(keyCode == 38){
                            
                    var Opoint = this.coo[1]; // p , q
                    var temX0 = this.coo[0].x;
                    var temY0 = this.coo[0].y;
                    var temX2 = this.coo[2].x;
                    var temY2 = this.coo[2].y;
                    var temX3 = this.coo[3].x;
                    var temY3 = this.coo[3].y;
                    this.coo[0].x = temY0 - Opoint.y + Opoint.x;
                    this.coo[0].y = Opoint.x - temX0  + Opoint.y;
                    this.coo[2].x = temY2 - Opoint.y + Opoint.x;
                    this.coo[2].y = Opoint.x - temX2  + Opoint.y;
                    this.coo[3].x = temY3 - Opoint.y + Opoint.x;
                    this.coo[3].y = Opoint.x - temX3  + Opoint.y;
                    if(this.checkTouch(this.coo)){
                        this._changePosition(this.coo);
                    }else{
                        this.coo[0].x =temX0;
                        this.coo[0].y = temY0;
                        this.coo[2].x = temX2;
                        this.coo[2].y = temY2;
                        this.coo[3].x = temX3;
                        this.coo[3].y = temY3;
                    }
                }
            }
        }

/****************************华丽丽的分割线***************************/

        //主游戏循环;
        var SPEED = 400;
        var startGame = false;
        var myBoard = new mainBoard(10,18,20);
        var myBlock = new block(myBoard,3,0);
        var count = 0;
        var countP = $("<p id='count' style='text-align:center;font-size:24px;margin:2px;'>得分：0</p>");
        $("body").append(countP);
        myBoard.show();
        myBlock.create();
       
        $(document).on("keydown",function(event){
            if(startGame){
                //console.log(event.keyCode)
                myBlock.move(event.keyCode)
                myBlock.rotate(event.keyCode)
                if(!myBlock.active){
                    var destroyCount =  myBlock.destroy();
                    count += destroyCount;
                    $("#count").text("得分："+count);
                    var overFlag = myBlock.CheckGameOver();
                    if(!overFlag){
                        myBlock = new block(myBoard,3,0);
                        myBlock.create();
                    }
                }
            }else{
                return false;
            }
            
        })
        
        function autoGame(){
            var gameover = false;
            var timer = setTimeout(function(){
                clearTimeout(timer);
                myBlock.AutoMoveDown();
                if(!myBlock.active){
                    var destroyCount =  myBlock.destroy();
                    count += destroyCount;
                    $("#count").text("得分："+count);
                    var overFlag = myBlock.CheckGameOver();
                    if(!overFlag){
                        myBlock = new block(myBoard,3,0);
                        myBlock.create();
                    }else{
                        gameover = true;
                    }
                }
                if(gameover){
                    alert("游戏结束");
                }else{
                    autoGame();
                }
            },SPEED);
        }
    
        $("#startGame").on("click",function(){
            startGame = true;
            autoGame();
            $(this).attr("disabled","true");
        })



    })
</script>